﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using Cashier.utils;
using System.Drawing;
using System.Text.RegularExpressions;

namespace Cashier.usercontrols
{
    public class TextboxExt: TextBox
    {
        public TextboxExt()
            : base()
        {
        }

        private bool isvalidate = false;

        [Category("Custom Attribute")]
        [Description("是否需要验证，默认false")]
        [Browsable(true)]
        public bool Isvalidate
        {
            get { return isvalidate; }
            set { isvalidate = value; }
        }

        private DataType datatype = DataType.Varchar;

        [Category("Custom Attribute")]
        [Description("验证数据类型，默认为字符串")]
        [Browsable(true)]
        public DataType Datatype
        {
            get { return datatype; }
            set { datatype = value; }
        }

        private int minlength = 0;

        [Category("Custom Attribute")]
        [Description("字符串最小长度，0表示不验证长度")]
        [Browsable(true)]
        public int Minlength
        {
            get { return minlength; }
            set { minlength = value; }
        }

        private bool ispassed = false;

        /// <summary>
        /// 是否验证通过
        /// </summary>
        [Browsable(false)]
        public bool Ispassed
        {
            get 
            {
                if (!ishappenevent)
                    this.Validate();
                return ispassed = (isvalidate ? ispassed : true); 
            }
        }

        private double minnumber = -1;

        [Category("Custom Attribute")]
        [Description("最小数值，默认-1代表不验证")]
        [Browsable(true)]
        public double Minnumber
        {
            get { return minnumber; }
            set { minnumber = value; }
        }

        private double maxnumber = 0;

        [Category("Custom Attribute")]
        [Description("最大数值")]
        [Browsable(true)]
        public double Maxnumber
        {
            get { return maxnumber; }
            set { maxnumber = value; }
        }

        private bool actionEnterEvent = false;

        [Category("Custom Attribute")]
        [Description("是否外部响应Enter键事件，默认为false")]
        [Browsable(true)]
        public bool ActionEnterEvent
        {
            get { return actionEnterEvent; }
            set { actionEnterEvent = value; }
        }

        /// <summary>
        /// 是否发生事件
        /// </summary>
        private bool ishappenevent = false;

        /// <summary>
        /// 获得焦点事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);
            if (isvalidate)
            {
                if (datatype == DataType.Varchar && minlength > 0)
                {
                    if (this.BackColor == Color.Yellow)
                    {
                        this.ispassed = true;
                        this.BackColor = SystemColors.Window;
                    }
                }
            }
            if (this.Text.Equals("0.00") || this.Text.Equals("0"))
            {
                this.Tag = this.Text;
                this.Text = String.Empty;
            }
        }

        /// <summary>
        /// 失去焦点事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);
            try
            {
                if (datatype == DataType.Money)
                {
                    if (!String.IsNullOrEmpty(this.Text))
                    {
                        if (this.Text.Contains("."))
                        {
                            String strDot = this.Text.Substring(this.Text.IndexOf(".") + 1);
                            if (strDot.Length == 1)
                            {
                                this.Text = this.Text + "0";
                            }
                            else if (strDot.Length > 2)
                            {
                                this.Text = this.Text.Substring(0, this.Text.IndexOf(".") + 3);
                            }
                        }
                        else
                        {
                            this.Text = this.Text + ".00";
                        }
                    }
                }

                this.Validate();
                if (String.IsNullOrEmpty(this.Text) && this.Tag != null && 
                    (this.Tag.ToString().Equals("0") || this.Tag.ToString().Equals("0.00")))
                {
                    this.Text = this.Tag.ToString();
                    this.Tag = null;
                }
            }
            catch (Exception ex)
            {
                LogsUtil.Record(ex);
            }
            ishappenevent = true;
        }

        /// <summary>
        /// 键盘事件
        /// </summary>
        /// <param name="e"></param>
        /// 48-57  > 0-9
        /// BACK   > 8
        /// Ctrl+C > 3
        /// Ctrl+V > 22
        /// 小数点 > 46
        /// 减号-  > 45
        /// 加号+  > 43
        /// 左右括号() > 40,41
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            base.OnKeyPress(e);
            int keyValue = (int)e.KeyChar;

            if (datatype == DataType.Integer)
            {
                if (!((keyValue > 47 && keyValue < 58) || keyValue == 8))
                    e.Handled = true;
            }
            else if (datatype == DataType.Number || datatype == DataType.Money)
            {
                if (!((keyValue > 47 && keyValue < 58) || keyValue == 8 || keyValue == 46))
                    e.Handled = true;
            }
            else if (datatype == DataType.Phonenumber)
            {
                if (!((keyValue > 47 && keyValue < 58) || keyValue == 8 || keyValue == 46 || keyValue == 45
                        || keyValue == 43 || keyValue == 40 || keyValue == 41 || keyValue == 3 || keyValue == 22))
                    e.Handled = true;
            }
            else if (datatype == DataType.NumberAndLetter)
            {
                if (!((keyValue > 47 && keyValue < 58) || (keyValue > 96 && keyValue < 123) || keyValue == 8))
                    e.Handled = true;
            }
        }

        /// <summary>
        /// 下一控件焦点
        /// </summary>
        /// <param name="keyData"></param>
        /// <returns></returns>
        protected override bool ProcessDialogKey(Keys keyData)
        {
            if (!actionEnterEvent && keyData == Keys.Enter)
                keyData = Keys.Tab;
            return base.ProcessDialogKey(keyData);
        }

        /// <summary>
        /// 验证程序
        /// </summary>
        private void Validate()
        {
            if (isvalidate)
            {
                String value = String.IsNullOrEmpty(this.Text) ? String.Empty : this.Text.Trim();
                if (datatype == DataType.Varchar && minlength > 0)
                {
                    if (value.Length >= minlength)
                    {
                        this.ispassed = true;
                    }
                    else
                    {
                        this.ispassed = false;
                    }
                }
                else if ((datatype == DataType.NumberAndLetter || datatype == DataType.Phonenumber) && minlength > 0)
                {
                    if (value.Length >= minlength && Regex.IsMatch(value, RegexExpress.LETTER_NUMBER))
                    {
                        this.ispassed = true;
                    }
                    else
                    {
                        this.ispassed = false;
                    }
                }
                else if (datatype == DataType.Number || datatype == DataType.Money)
                {
                    if (String.IsNullOrEmpty(value))
                    {
                        this.ispassed = false;
                    }
                    else
                    {
                        if ((datatype == DataType.Number && Regex.IsMatch(value, RegexExpress.NUMBER)) ||
                            (datatype == DataType.Money && Regex.IsMatch(value, RegexExpress.DECIMAL_TWO_BITS)))
                        {
                            double number = Double.Parse(value);
                            if (minnumber > 0)
                            {
                                if (number >= minnumber)
                                    this.ispassed = true;
                                else
                                    this.ispassed = false;
                            }
                            else if (maxnumber > 0)
                            {
                                if (number <= maxnumber)
                                    this.ispassed = true;
                                else
                                    this.ispassed = false;
                            }
                            else
                                this.ispassed = true;
                        }
                        else
                            this.ispassed = false;
                    }
                }
                else
                    this.ispassed = true;

                if (!this.ispassed)
                    this.BackColor = Color.Yellow;
                else
                    this.BackColor = SystemColors.Window;
            }
        }

        /// <summary>
        /// 文本值转换为Decimal
        /// </summary>
        public Decimal TextValueToDecimal
        {
            get
            {
                Decimal textValue = 0M;
                if (!String.IsNullOrEmpty(this.Text.Trim()) && Regex.IsMatch(this.Text.Trim(), RegexExpress.DECIMAL_TWO_BITS))
                {
                    textValue = Convert.ToDecimal(this.Text.Trim());
                }
                return textValue;
            }
        }

        /// <summary>
        /// 文件转换为Int32
        /// </summary>
        public Int32 TextValueToInt32
        {
            get
            {
                Int32 textValue = 0;
                if (!String.IsNullOrEmpty(this.Text.Trim()) && Regex.IsMatch(this.Text.Trim(), RegexExpress.ZERO_AND_NUMBER))
                {
                    textValue = Convert.ToInt32(this.Text.Trim());
                }
                return textValue;
            }
        }
    }
}
